//
//  FilterChecksCell.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/3/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit
import SnapKit



final class FilterChecksCell: UITableViewCell, ConfigurableCell {
    
    // MARK: - Outlets
    
    private lazy var mainStack:UIStackView = {
        let stack = UIStackView()
        stack.axis = .vertical
        stack.alignment = .fill
        stack.distribution = .equalSpacing
        stack.spacing = 12.0
        return stack
    }()
    
    private lazy var personSegmented: RoundedSCView = {
        let view = RoundedSCView()
        view.updateItems(items: PersonType.allCases.map {$0.rawValue})
        return view
    }()
    
    private lazy var stateField: ModalElement = {
        let element = ModalElement()
        element.delegate = self
        element.modal = .state
        element.updateUI(value: nil, placeholder: "Состояние")
        element.snp.makeConstraints { (make) in
            make.height.equalTo(48)
        }
        return element
    }()
    
    private lazy var monthPurchaseField: ModalElement = {
        let element = ModalElement()
        element.delegate = self
        element.modal = .monthPurchase
        element.updateUI(value: nil, placeholder: "Ежемесячный платеж")
        element.snp.makeConstraints { (make) in
            make.height.equalTo(48)
        }
        return element
    }()
    
    private lazy var firstPurchaseField: ModalElement = {
        let element = ModalElement()
        element.delegate = self
        element.modal = .firstPurchase
        element.updateUI(value: nil, placeholder: "Первоначальный платеж")
        element.snp.makeConstraints { (make) in
            make.height.equalTo(48)
        }
        return element
    }()
    
    // MARK: - Properties
    
    private var fields: [OptionItem] = []
    private var index: Int!
    private var modals: [ModalView.ModalType: [ModalView.ModalData]] = [:]
    private var rangeData: [ModalView.ModalType: [Int?]] = [:]
    @Range var normalizedTemplate = ""
    // MARK: - Actions
    
    @objc private func onCheckBoxSelect (sender: OptionTap) {
        fields[sender.indexPath.item].toggleSelection()
    }
    
    
    // MARK: - Init
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        self.addViews()
        NotificationCenter.default.addObserver(self, selector: #selector(returnData(notification:)), name: NSNotification.Name(rawValue: "sendModal"), object: nil)
    }
        
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: "sendModal"), object: nil)
    }
    
    // MARK: - Methods
    
    func configure(data object: Filter.FilterChecks, index: Int) {
        self.index = index
        
        self.personSegmented.transportSelect.selectedSegmentIndex = PersonType.allCases.firstIndex(of: object.personType)!
        
        if let carState = object.carState {
            modals[.state] = carState
            self.stateField.updateUI(value: carState.map {$0.name}.joined(separator: ", "))
        }
        
        rangeData[.firstPurchase] = [object.firstPurchaseFrom, object.firstPurchaseTo]
        rangeData[.monthPurchase] = [object.monthPurchaseFrom, object.monthPurchaseTo]
        
        self.updatePickers(modal: .firstPurchase, data: rangeData[.firstPurchase]!)
        self.updatePickers(modal: .monthPurchase, data: rangeData[.monthPurchase]!)
        
        for (i, key) in Filter.FilterChecks.keys.allCases.enumerated() {
            fields[i].updateSelection(isSelected: object[key.rawValue] ?? false)
        }
    }
    
    func returnData() -> Filter.FilterChecks {
        let personType = PersonType.allCases[personSegmented.transportSelect.selectedSegmentIndex]
        
        let firstPurch = rangeData[.firstPurchase]!
        let monthPurch = rangeData[.monthPurchase]!

        return Filter.FilterChecks(personType: personType,
                                   carState: modals[.state],
                                   firstPurchaseFrom: firstPurch.item(at: 0) ?? nil,
                                   firstPurchaseTo: firstPurch.item(at: 1) ?? nil,
                                   monthPurchaseFrom: monthPurch.item(at: 0) ?? nil,
                                   monthPurchaseTo: monthPurch.item(at: 1) ?? nil,
                                   rastomozhenInKZ: fields[0].getValue(),
                                   isGuarantee: fields[1].getValue(),
                                   isObmen: fields[2].getValue(),
                                   onlyPhoto: fields[3].getValue(),
                                   isCredit: fields[4].getValue(),
                                   noFee: fields[5].getValue())
    }
}

extension FilterChecksCell: ModalElementProtocol {
    func selectElement(modal: ModalView.ModalType?, customID: Int?) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "openModal"), object: nil, userInfo: ["modal": modal!])
    }
    
    func didClear(modal: ModalView.ModalType) {
        if modal == .state {
            self.modals[modal] = nil
            self.stateField.updateUI(value: nil)
        } else if modal == .firstPurchase {
            self.rangeData[modal] = nil
            self.firstPurchaseField.updateUI(value: nil)
        } else {
            self.rangeData[modal] = nil
            self.monthPurchaseField.updateUI(value: nil)
        }
    }
}


// MARK: - Adding views to superview

extension FilterChecksCell {
    
    private func addViews () {
        self.contentView.backgroundColor = .white
        self.contentView.addSubview(mainStack)
        mainStack.addArrangedSubview(personSegmented)
        mainStack.addArrangedSubview(stateField)
        
        self.applyConstraints()
        
        for (i, key) in Filter.FilterChecks.keys.allCases.enumerated() {
            self.createField(index: i, key: key)
        }
        mainStack.addArrangedSubview(monthPurchaseField)
        mainStack.addArrangedSubview(firstPurchaseField)
    }
    
    private func applyConstraints() {
        mainStack.snp.makeConstraints { (make) in
            make.leading.trailing.top.bottom.equalToSuperview().inset(16)
        }
        personSegmented.snp.makeConstraints { (make) in
            make.height.equalTo(40)
        }
    }
    
    /// Creating Field With Checkbox
    /// - Parameters:
    ///   - index: index among other checboxes ( from 0 )
    ///   - key: FilterChecks.key
    private func createField (index: Int, key: Filter.FilterChecks.keys){
        let field = OptionItem(customSize: true, showArrow: false)
        field.initialize(isSingle: true, title: key.rawValue, isMain: false)
        field.snp.makeConstraints { (make) in
            make.height.equalTo(48)
        }
        field.backgroundColor = .whiteBlueColor
        field.layer.borderWidth = 0.0
        
        let tap = OptionTap(target: self, action: #selector(onCheckBoxSelect(sender:)))
        tap.indexPath = IndexPath(item: index, section: 0)
        field.addGestureRecognizer(tap)
        fields.append(field)
        mainStack.addArrangedSubview(field)
    }
    
    /// Creating modal opener button
    /// - Parameter modal: Type of modal (Пробег, цена и тд)
    /// - Returns: Modal Element view
    private func createModalButton (modal: ModalView.ModalType) -> ModalElement {
        let btn = ModalElement()
        btn.updateUI(value: nil, placeholder: modal.rawValue)
        btn.modal = modal
        btn.delegate = self
        btn.snp.makeConstraints { (make) in
            make.height.equalTo(48)
        }
        return btn
    }
    
}

// MARK: - Main Actions

extension FilterChecksCell {
    
    /// Callback from Modal View
    /// - Parameter notification: Contains information about selected items
    @objc private func returnData (notification: NSNotification) {
        if let userInfo = notification.userInfo {
            let modal = userInfo["type"] as! ModalView.ModalType
            if modal == .state {
                let data = userInfo["data"] as! [ModalView.ModalData]
                self.updateTableViews(modal: modal, data: data)
            } else if modal == .monthPurchase || modal == .firstPurchase {
                let data = userInfo["data"] as! [Double?]
                let intFrom = data.count > 0 && data[0] != nil ? Int(data[0]!) : nil
                let intTo = data.count > 1 && data[1] != nil ? Int(data[1]!) : nil
                self.updatePickers(modal: modal, data: [intFrom, intTo])
            }
        }
    }
    
    /// Updating fields in table view cell
    /// - Parameters:
    ///   - modal: Modal's type: (Пробег, Цена, and other range types)
    ///   - data: [<#from#>, <#to#>]: [Int, Int]
    private func updatePickers (modal: ModalView.ModalType, data: [Int?]) {
        
        self.rangeData[modal] = data
        let template = "\(data[0] ?? 0)-\(data[1] ?? 0)"
        normalizedTemplate = template
        
        if modal == .monthPurchase {
            self.monthPurchaseField.updateUI(value: normalizedTemplate)
        } else {
            self.firstPurchaseField.updateUI(value: normalizedTemplate)
        }
    }
    
    /// Reloading UITableViewController
    /// - Parameters:
    ///   - modal: Modal's type: (Пробег, Цена, and other range types)
    ///   - data: [ModalView.ModalData] - multiple selected items, contains  <#name#>,, <#id#>
    private func updateTableViews (modal: ModalView.ModalType, data: [ModalView.ModalData]) {
        let dataValues = data.map { $0.name }
        self.stateField.updateUI(value: dataValues.joined(separator: ", "))
        self.modals[modal] = data
    }
}
